#ifndef UTILS_CPP
#define UTILS_CPP

#include <iostream>
#include <sys/types.h>
#include <sys/shm.h>


// MACROS
#define SQR(x) ((x)*(x))

// NAMESPACES
using namespace std;

// TYPES
typedef unsigned int uint;
typedef long int lint;
typedef long unsigned int luint;
typedef long long unsigned int lluint;

typedef float real;
typedef double lreal;
typedef long double llreal;
		
// FUNCTIONS

// arrays allignment
char *new_align(uint N, uint size, uint align){
	char *arr = new char[(N+align/8)*size];
	arr+=(luint)arr%align;
	return arr;
}

char *new_align(uint n, uint size, uint align, char* &ptr){
	ptr = new char[(n+align/8)*size];
	
	
	char *arr =ptr;
	arr+=(luint)arr%align;
	
	//printf("%u\n%u\n\n", (luint)ptr,  (luint)arr);
	return arr;
}

// shatred memory
void *new_shm(int key, uint size){
	int id = shmget(key, size, IPC_CREAT | 0666); // set seg with 'key' and 'size'
	return shmat(id, NULL, 0);
}
	
void *new_shm(int key, uint size, char* addr){
	shmdt(addr);
	int id = shmget(key, 1, 0666);
	shmctl(id, IPC_RMID, NULL); // and erase it
	id = shmget(key, size, IPC_CREAT | 0666); // set seg with 'key' and 'size'
	return shmat(id, NULL, 0);
}

//NOTE do not use with inline or 03 optimization
float isqrt(float number )
{
        
	register unsigned int i;
	register float x2, y;
	register const float threehalfs = 1.5f;
   x2 = number * 0.5f;
   y  = number;
   i  = * ( unsigned int * ) &y;               // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
 
	return y;
}

// the same precition as std::sqrt
double isqrt(double number){ 
	
	unsigned long int i;       
	double x2, y;       
	const double threehalfs = 1.5;       
	x2 = number * 0.5;       
	y = number;       
	i = * ( unsigned long int * ) &y;       
	i = 0x5fe6ec85e7de30da - ( i >> 1 );       
	y = *( double * ) &i;       
	y = y * ( threehalfs -  x2 * y*y  ); // 1st iteration       
	//y = y * ( threehalfs -  x2 * y*y ); // 2nd iteration, this can be removed
	//return  y * ( threehalfs -  x2 * y * y  ); // 2nd iteration, this can be removed       
	return  y;
} 

#include <sys/stat.h>  // for file size
int getFileSize(const char* fullfilename){
	struct stat results;
	stat(fullfilename, &results);
	return results.st_size;
}



#endif